{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "06e5af38-85ad-46b6-a5ea-52a7ff947853",
   "metadata": {},
   "source": [
    "# Labelme转COCO-单个文件\n",
    "\n",
    "同济子豪兄 呕心沥血写成\n",
    "\n",
    "兼容目标检测、图像分割、关键点检测三种标注\n",
    "\n",
    "2023-3-9\n",
    "\n",
    "2023-3-10\n",
    "\n",
    "2023-4-15\n",
    "\n",
    "2023-4-16\n",
    "\n",
    "2023-4-21"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b0a8a2a1-fb46-4d51-8b4f-cd0568bc13f8",
   "metadata": {},
   "source": [
    "## 导入工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "5969d148-19e6-4b2e-9797-01105b87b56c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "75c4fd53-f3ce-4a27-9024-6abec83717d9",
   "metadata": {},
   "source": [
    "## 删除系统自动生成的多余文件\n",
    "\n",
    "建议在 Linux 系统中运行爬虫、划分训练集测试集代码"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7ecd3ad-874c-46cc-ac47-6f4ae3adf07a",
   "metadata": {},
   "source": [
    "### 查看待删除的多余文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a8356247-4b89-42e9-aa87-4c630f05e1f8",
   "metadata": {},
   "outputs": [],
   "source": [
    "!find . -iname '__MACOSX'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a1b64d9d-bdf8-43fe-8321-bb6d241137dc",
   "metadata": {},
   "outputs": [],
   "source": [
    "!find . -iname '.DS_Store'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "a5f038c2-72ba-4724-a190-b2ec97d8bcf0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "./output_coco/.ipynb_checkpoints\n",
      "./.ipynb_checkpoints\n"
     ]
    }
   ],
   "source": [
    "!find . -iname '.ipynb_checkpoints'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "191ccc29-baeb-46ff-8125-71c49adee533",
   "metadata": {},
   "source": [
    "### 删除多余文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "4bf04f95-0750-4248-8696-fa2aa4ff03e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "!for i in `find . -iname '__MACOSX'`; do rm -rf $i;done"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "217b2325-835b-451c-89d7-3d39c5dfc5c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "!for i in `find . -iname '.DS_Store'`; do rm -rf $i;done"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "cfb7afa4-106a-4e6a-ab35-86f0eb902432",
   "metadata": {},
   "outputs": [],
   "source": [
    "!for i in `find . -iname '.ipynb_checkpoints'`; do rm -rf $i;done"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a2904f2-93ba-4726-9b2b-b8285511a760",
   "metadata": {},
   "source": [
    "### 验证多余文件已删除"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "33239471-a70e-426d-beba-3517c14311e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "!find . -iname '__MACOSX'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f82a7703-8b94-4103-9672-ec29849616b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "!find . -iname '.DS_Store'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "0101460a-d0bc-4388-aa0b-d30b0f0ef538",
   "metadata": {},
   "outputs": [],
   "source": [
    "!find . -iname '.ipynb_checkpoints'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b4fb7ee-0886-416c-bbaf-6c2dfe7e63c9",
   "metadata": {},
   "source": [
    "## 载入一个labelme格式的json标注文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b17d0e7a-b987-4784-9dfe-a67ebfeefb15",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('1.json', 'r', encoding='utf-8') as f:\n",
    "    labelme = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2c2b711c-4e34-459b-854f-bfdda7170935",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['version', 'flags', 'shapes', 'imagePath', 'imageData', 'imageHeight', 'imageWidth'])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labelme.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "979f8578-9c1c-4b32-b98e-53838d0ef5fe",
   "metadata": {},
   "source": [
    "## 元数据 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9fb38995-4ecc-44b4-a132-1d6851f18961",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'5.1.1'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labelme['version']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "376d7a49-d5a1-4827-b68e-7334a231a144",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labelme['flags']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "1733f8f9-72d4-47f8-a010-2ab98b724afa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'1.jpg'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 图像文件名\n",
    "labelme['imagePath']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "c0411a3c-8e43-4878-8657-cbdca9e15c18",
   "metadata": {},
   "outputs": [],
   "source": [
    "labelme['imageData']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9bc00c97-9d5f-4664-b502-631cdf2a15b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2736"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 图像高度\n",
    "labelme['imageHeight']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "8185cf9e-84ba-4081-8e4a-db189b10d29e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3648"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 图像宽度\n",
    "labelme['imageWidth']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68bd2fd7-914f-4ebc-a65e-bf43ceb87761",
   "metadata": {},
   "source": [
    "## 标注信息"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "2ddb2f62-b076-491f-83cf-aa4f12c82ea3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'label': 'Triangle_30',\n",
       "  'points': [[172.52941176470614, 100.35294117647076],\n",
       "   [2054.8823529411766, 976.8235294117648]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'rectangle',\n",
       "  'flags': {}},\n",
       " {'label': 'Triangle_45',\n",
       "  'points': [[2422.529411764706, 432.70588235294133],\n",
       "   [3569.5882352941176, 1673.8823529411766]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'rectangle',\n",
       "  'flags': {}},\n",
       " {'label': 'Angle',\n",
       "  'points': [[1128.4117647058827, 1000.3529411764706],\n",
       "   [2510.764705882353, 1844.4705882352944]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'rectangle',\n",
       "  'flags': {}},\n",
       " {'label': 'Ruler',\n",
       "  'points': [[290.17647058823553, 2029.764705882353],\n",
       "   [2510.764705882353, 2626.8235294117644]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'rectangle',\n",
       "  'flags': {}},\n",
       " {'label': 'Triangle_30_poly',\n",
       "  'points': [[2040.1764705882354, 735.6470588235295],\n",
       "   [566.6470588235296, 106.23529411764723],\n",
       "   [181.3529411764708, 947.4117647058824]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'polygon',\n",
       "  'flags': {}},\n",
       " {'label': 'Triangle_45_poly',\n",
       "  'points': [[3504.882352941176, 1653.294117647059],\n",
       "   [3557.8235294117644, 523.8823529411766],\n",
       "   [2431.3529411764703, 450.3529411764707]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'polygon',\n",
       "  'flags': {}},\n",
       " {'label': 'Ruler_poly',\n",
       "  'points': [[343.11764705882376, 2047.4117647058827],\n",
       "   [313.70588235294144, 2444.470588235294],\n",
       "   [2478.4117647058824, 2597.4117647058824],\n",
       "   [2496.0588235294117, 2197.4117647058824]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'polygon',\n",
       "  'flags': {}},\n",
       " {'label': 'Angle_poly',\n",
       "  'points': [[1151.9411764705885, 1697.4117647058824],\n",
       "   [1166.6470588235295, 1544.4705882352944],\n",
       "   [1210.7647058823532, 1388.5882352941178],\n",
       "   [1310.7647058823532, 1247.4117647058824],\n",
       "   [1443.1176470588236, 1132.7058823529414],\n",
       "   [1599.0000000000002, 1050.3529411764707],\n",
       "   [1772.529411764706, 1018.0000000000001],\n",
       "   [1969.5882352941178, 1023.8823529411765],\n",
       "   [2113.705882352941, 1076.8235294117649],\n",
       "   [2257.8235294117644, 1162.1176470588236],\n",
       "   [2381.3529411764703, 1297.4117647058824],\n",
       "   [2443.1176470588234, 1418.0000000000002],\n",
       "   [2490.176470588235, 1579.7647058823532],\n",
       "   [2499.0, 1738.5882352941178],\n",
       "   [2475.470588235294, 1832.7058823529412]],\n",
       "  'group_id': None,\n",
       "  'shape_type': 'polygon',\n",
       "  'flags': {}}]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "labelme['shapes']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e2093d2-f904-40da-b06f-8e844bf86d72",
   "metadata": {},
   "source": [
    "## 创建coco格式的字典"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "270c366b-3283-4e2f-acf1-79fb9f6f8af5",
   "metadata": {},
   "outputs": [],
   "source": [
    "coco = {}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "76e3dae4-2846-4f7b-ae86-477f1bb52ec1",
   "metadata": {},
   "source": [
    "## info"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "3113d81f-e367-45b1-b954-bc0e51901625",
   "metadata": {},
   "outputs": [],
   "source": [
    "# coco['info'] = {}\n",
    "# coco['info']['description'] = 'Labelme2coco keypoint format script from Zihao'\n",
    "# coco['info']['year'] = 2023\n",
    "# coco['info']['date_created'] = '2023/03/09'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e974eff3-dbbe-44e1-85f1-5df97ec43bb6",
   "metadata": {},
   "source": [
    "## 类别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d5300c79-48a3-40f4-a0c8-7dd4a6388aa8",
   "metadata": {},
   "outputs": [],
   "source": [
    "class_list= [\n",
    "    {'id': 0, 'name': 'Triangle_30'},\n",
    "    {'id': 1, 'name': 'Triangle_45'},\n",
    "    {'id': 2, 'name': 'Angle'},\n",
    "    {'id': 3, 'name': 'Ruler'}\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "6ff4ee32-5eb0-490d-a316-323101ba2e44",
   "metadata": {},
   "outputs": [],
   "source": [
    "label2id = {}\n",
    "for each in class_list:\n",
    "    label2id[each['name']] = each['id']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "4d9c9be8-9f09-4cd4-a834-e071eda7712d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'Triangle_30': 0, 'Triangle_45': 1, 'Angle': 2, 'Ruler': 3}"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "label2id"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "9e4ab405-1aef-484a-8d39-8d565f54204f",
   "metadata": {},
   "outputs": [],
   "source": [
    "coco['categories'] = class_list\n",
    "coco['images'] = []\n",
    "coco['annotations'] = []\n",
    "\n",
    "IMG_ID = 0\n",
    "ANN_ID = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68f2d4e8-824d-4b19-b529-632c85de25ec",
   "metadata": {},
   "source": [
    "## 函数-处理单个labelme标注json文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "a53dbf74-7e72-4ef0-b39e-e03baa198a21",
   "metadata": {},
   "outputs": [],
   "source": [
    "def process_single_json(labelme, image_id=1):\n",
    "    '''\n",
    "    输入labelme的json数据，输出coco格式的每个框的关键点标注信息\n",
    "    '''\n",
    "    \n",
    "    global ANN_ID\n",
    "    \n",
    "    coco_annotations = []\n",
    "    \n",
    "    for each_ann in labelme['shapes']: # 遍历该json文件中的所有标注\n",
    "\n",
    "        if each_ann['shape_type'] == 'rectangle': # 筛选出框\n",
    "\n",
    "            ## 该框的元数据\n",
    "            bbox_dict = {}\n",
    "            # 该框的类别 信息\n",
    "            bbox_dict['category_id'] = label2id[each_ann['label']]\n",
    "            bbox_dict['segmentation'] = []\n",
    "            \n",
    "            bbox_dict['iscrowd'] = 0\n",
    "            bbox_dict['image_id'] = image_id\n",
    "            bbox_dict['id'] = ANN_ID\n",
    "            ANN_ID += 1\n",
    "\n",
    "            # 获取框坐标\n",
    "            bbox_left_top_x = min(int(each_ann['points'][0][0]), int(each_ann['points'][1][0]))\n",
    "            bbox_left_top_y = min(int(each_ann['points'][0][1]), int(each_ann['points'][1][1]))\n",
    "            bbox_right_bottom_x = max(int(each_ann['points'][0][0]), int(each_ann['points'][1][0]))\n",
    "            bbox_right_bottom_y = max(int(each_ann['points'][0][1]), int(each_ann['points'][1][1]))\n",
    "            bbox_w = bbox_right_bottom_x - bbox_left_top_x\n",
    "            bbox_h = bbox_right_bottom_y - bbox_left_top_y\n",
    "            bbox_dict['bbox'] = [bbox_left_top_x, bbox_left_top_y, bbox_w, bbox_h] # 左上角x、y、框的w、h\n",
    "            bbox_dict['area'] = bbox_w * bbox_h\n",
    "            \n",
    "            # 筛选出分割多段线\n",
    "            for each_ann in labelme['shapes']: # 遍历所有标注\n",
    "                if each_ann['shape_type'] == 'polygon': # 筛选出分割多段线标注\n",
    "                    # 第一个点的坐标\n",
    "                    first_x = each_ann['points'][0][0]\n",
    "                    first_y = each_ann['points'][0][1]\n",
    "                    if (first_x>bbox_left_top_x) & (first_x<bbox_right_bottom_x) & (first_y<bbox_right_bottom_y) & (first_y>bbox_left_top_y): # 筛选出在该个体框中的关键点\n",
    "                        bbox_dict['segmentation'] = list(map(lambda x: list(map(lambda y: round(y, 2), x)), each_ann['points'])) # 坐标保留两位小数\n",
    "                    \n",
    "            coco_annotations.append(bbox_dict)\n",
    "            \n",
    "    return coco_annotations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb0000c2-7255-488b-8585-d87af4c849b0",
   "metadata": {},
   "source": [
    "## 测试一下函数的效果，处理单个labelme格式的json标注文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "5235f915-a441-43c3-9cdf-2eab3698d1c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "labelme_json_path = '1.json'\n",
    "\n",
    "with open(labelme_json_path, 'r', encoding='utf-8') as f:\n",
    "    labelme = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "1c68653e-fcc0-413c-b96d-2befbd370788",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'category_id': 0,\n",
       "  'segmentation': [[2040.18, 735.65], [566.65, 106.24], [181.35, 947.41]],\n",
       "  'iscrowd': 0,\n",
       "  'image_id': 1,\n",
       "  'id': 0,\n",
       "  'bbox': [172, 100, 1882, 876],\n",
       "  'area': 1648632},\n",
       " {'category_id': 1,\n",
       "  'segmentation': [[3504.88, 1653.29], [3557.82, 523.88], [2431.35, 450.35]],\n",
       "  'iscrowd': 0,\n",
       "  'image_id': 1,\n",
       "  'id': 1,\n",
       "  'bbox': [2422, 432, 1147, 1241],\n",
       "  'area': 1423427},\n",
       " {'category_id': 2,\n",
       "  'segmentation': [[1151.94, 1697.41],\n",
       "   [1166.65, 1544.47],\n",
       "   [1210.76, 1388.59],\n",
       "   [1310.76, 1247.41],\n",
       "   [1443.12, 1132.71],\n",
       "   [1599.0, 1050.35],\n",
       "   [1772.53, 1018.0],\n",
       "   [1969.59, 1023.88],\n",
       "   [2113.71, 1076.82],\n",
       "   [2257.82, 1162.12],\n",
       "   [2381.35, 1297.41],\n",
       "   [2443.12, 1418.0],\n",
       "   [2490.18, 1579.76],\n",
       "   [2499.0, 1738.59],\n",
       "   [2475.47, 1832.71]],\n",
       "  'iscrowd': 0,\n",
       "  'image_id': 1,\n",
       "  'id': 2,\n",
       "  'bbox': [1128, 1000, 1382, 844],\n",
       "  'area': 1166408},\n",
       " {'category_id': 3,\n",
       "  'segmentation': [[343.12, 2047.41],\n",
       "   [313.71, 2444.47],\n",
       "   [2478.41, 2597.41],\n",
       "   [2496.06, 2197.41]],\n",
       "  'iscrowd': 0,\n",
       "  'image_id': 1,\n",
       "  'id': 3,\n",
       "  'bbox': [290, 2029, 2220, 597],\n",
       "  'area': 1325340}]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "process_single_json(labelme)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92bf92c2-2760-4419-8ec0-376fa8f2c94c",
   "metadata": {
    "tags": []
   },
   "source": [
    "## images和annotations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "2cabd690-f506-4409-91e2-72b58778be09",
   "metadata": {},
   "outputs": [],
   "source": [
    "IMG_ID = 0\n",
    "ANN_ID = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "8ff03c44-d52f-4ea4-aabe-c5a431f202b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.json 已处理完毕\n"
     ]
    }
   ],
   "source": [
    "# 遍历所有 labelme 格式的 json 文件\n",
    "for labelme_json in os.listdir(): \n",
    "    \n",
    "    if labelme_json.split('.')[-1] == 'json':\n",
    "        \n",
    "        with open(labelme_json, 'r', encoding='utf-8') as f:\n",
    "            \n",
    "            labelme = json.load(f)\n",
    "            \n",
    "            ## 提取图像元数据\n",
    "            img_dict = {}\n",
    "            img_dict['file_name'] = labelme['imagePath']\n",
    "            img_dict['height'] = labelme['imageHeight']\n",
    "            img_dict['width'] = labelme['imageWidth']\n",
    "            img_dict['id'] = IMG_ID\n",
    "            coco['images'].append(img_dict)\n",
    "            \n",
    "            ## 提取框和关键点信息\n",
    "            coco_annotations = process_single_json(labelme, image_id=IMG_ID)\n",
    "            coco['annotations'] += coco_annotations\n",
    "            \n",
    "            IMG_ID += 1\n",
    "            \n",
    "            print(labelme_json, '已处理完毕')\n",
    "\n",
    "    else:\n",
    "        pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91297f39-cf9b-46e7-b8ec-d2dc3fe3caf8",
   "metadata": {},
   "source": [
    "## 保存为MS COCO格式的json标注文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "946d53ee-7ada-4428-bb4c-6b52eab88d32",
   "metadata": {},
   "outputs": [],
   "source": [
    "if not os.path.exists('output_coco'):\n",
    "    os.mkdir('output_coco')\n",
    "    print('创建新目录 output_coco')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "fa9e02a6-7d52-46ec-af90-b7192bda877d",
   "metadata": {},
   "outputs": [],
   "source": [
    "coco_path = 'output_coco/coco_sample.json'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "20f074ed-dd24-4f49-bdd9-26dd204d0714",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(coco_path, 'w') as f:\n",
    "    json.dump(coco, f, indent=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "2be6bf0b-8fb9-4708-a44d-5633ef2c8715",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'categories': [{'id': 0, 'name': 'Triangle_30'},\n",
       "  {'id': 1, 'name': 'Triangle_45'},\n",
       "  {'id': 2, 'name': 'Angle'},\n",
       "  {'id': 3, 'name': 'Ruler'}],\n",
       " 'images': [{'file_name': '1.jpg', 'height': 2736, 'width': 3648, 'id': 0}],\n",
       " 'annotations': [{'category_id': 0,\n",
       "   'segmentation': [[2040.18, 735.65], [566.65, 106.24], [181.35, 947.41]],\n",
       "   'iscrowd': 0,\n",
       "   'image_id': 0,\n",
       "   'id': 0,\n",
       "   'bbox': [172, 100, 1882, 876],\n",
       "   'area': 1648632},\n",
       "  {'category_id': 1,\n",
       "   'segmentation': [[3504.88, 1653.29], [3557.82, 523.88], [2431.35, 450.35]],\n",
       "   'iscrowd': 0,\n",
       "   'image_id': 0,\n",
       "   'id': 1,\n",
       "   'bbox': [2422, 432, 1147, 1241],\n",
       "   'area': 1423427},\n",
       "  {'category_id': 2,\n",
       "   'segmentation': [[1151.94, 1697.41],\n",
       "    [1166.65, 1544.47],\n",
       "    [1210.76, 1388.59],\n",
       "    [1310.76, 1247.41],\n",
       "    [1443.12, 1132.71],\n",
       "    [1599.0, 1050.35],\n",
       "    [1772.53, 1018.0],\n",
       "    [1969.59, 1023.88],\n",
       "    [2113.71, 1076.82],\n",
       "    [2257.82, 1162.12],\n",
       "    [2381.35, 1297.41],\n",
       "    [2443.12, 1418.0],\n",
       "    [2490.18, 1579.76],\n",
       "    [2499.0, 1738.59],\n",
       "    [2475.47, 1832.71]],\n",
       "   'iscrowd': 0,\n",
       "   'image_id': 0,\n",
       "   'id': 2,\n",
       "   'bbox': [1128, 1000, 1382, 844],\n",
       "   'area': 1166408},\n",
       "  {'category_id': 3,\n",
       "   'segmentation': [[343.12, 2047.41],\n",
       "    [313.71, 2444.47],\n",
       "    [2478.41, 2597.41],\n",
       "    [2496.06, 2197.41]],\n",
       "   'iscrowd': 0,\n",
       "   'image_id': 0,\n",
       "   'id': 3,\n",
       "   'bbox': [290, 2029, 2220, 597],\n",
       "   'area': 1325340}]}"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "coco"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19620709-b2dc-4db5-892f-8854702333e7",
   "metadata": {},
   "source": [
    "## 验证MS COCO格式的标注"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "56d2a364-4354-4742-bcc7-2c7e5e527b16",
   "metadata": {},
   "outputs": [],
   "source": [
    "# !pip install pycocotools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "10fa6971-4520-41fd-b6ca-5560bd2dad03",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading annotations into memory...\n",
      "Done (t=0.00s)\n",
      "creating index...\n",
      "index created!\n"
     ]
    }
   ],
   "source": [
    "from pycocotools.coco import COCO\n",
    "\n",
    "my_coco = COCO(coco_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32c73f79-4665-45a2-973e-3ce16635999a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
